package com.imis.module.system.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imis.base.annotation.HashCache;
import com.imis.base.annotation.HashCacheEvict;
import com.imis.base.constant.CacheConstant;
import com.imis.base.constant.DataBaseConstant;
import com.imis.module.api.model.ro.DictItemsByCodeQueryDTO;
import com.imis.module.api.model.ro.DictItemsQueryDTO;
import com.imis.module.base.impl.BaseServiceImpl;
import com.imis.module.system.dao.SysDictMapper;
import com.imis.module.system.model.converter.SysDictConverter;
import com.imis.module.system.model.po.SysDict;
import com.imis.module.system.model.ro.PagingQueryDictDTO;
import com.imis.module.system.model.ro.QueryDictTreeDTO;
import com.imis.module.system.model.vo.DictVO;
import com.imis.module.system.model.vo.DropDownBoxTreeVO;
import com.imis.module.system.model.vo.SysDictVO;
import com.imis.module.system.service.ISysDictService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 字典项 服务实现类
 * </p>
 *
 * @author XinLau
 * @since 2020-03-23
 */
@Service
@Slf4j
@DS(DataBaseConstant.DATA_SOURCE_MASTER)
public class SysDictServiceImpl extends BaseServiceImpl<SysDictMapper, SysDict> implements ISysDictService {

    /**
     * 通过查询指定code 获取字典值text
     *
     * @param code
     * @param key
     * @return String
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/4/15 10:03
     */
    @Override
    @HashCache(hashIdentification = CacheConstant.SYS_DICT_CACHE, hashKey = "#code + ':' + #key")
    public String queryDictTextByKey(final String code, final String key) {
        log.debug("无缓存 queryDictTextByKey 的时候调用这里！");
        return mapper.queryDictTextByKey(code, key);
    }

    /**
     * 通过查询指定表（table）的字段（text、code） 获取字典值text
     *
     * @param table - 表名
     * @param text  - 字段名
     * @param code  - 字段值
     * @param key   - 子表key
     * @return String
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/4/15 10:08
     */
    @Override
    @HashCache(hashIdentification = CacheConstant.SYS_DICT_CACHE, hashKey = "#table + ':' + #text + ':' + #code + ':' + #key")
    public String queryTableDictTextByKey(final String table, final String text, final String code, final String key) {
        log.debug("无缓存 queryTableDictTextByKey 的时候调用这里！");
        return mapper.queryTableDictTextByKey(table, text, code, key);
    }

    /**
     * 分页查询字典值
     *
     * @param pagingQueryDictDTO - 字典项查询对象
     * @return Page<SysDictVO>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    public Page<SysDictVO> pagingQuerySysDictListByParameter(final PagingQueryDictDTO pagingQueryDictDTO) {
        // 1.页码、页长
        Page<SysDict> sysDictPage = new Page<>(pagingQueryDictDTO.getPageNumber(), pagingQueryDictDTO.getPageSize());
        // 2.排序字段
        sysDictPage.addOrder(OrderItem.descs(DataBaseConstant.CREATE_TIME_FIELD, DataBaseConstant.UPDATE_TIME_FIELD));
        // 3.条件分页查询
        sysDictPage = mapper.pagingQuerySysDictListByParameter(sysDictPage, pagingQueryDictDTO);
        // 4.PO分页对象转VO实体分页对象
        return SysDictConverter.INSTANCE.getDictReturnValueList(sysDictPage);
    }

    /**
     * 查询字典项
     *
     * @param dictName - 字典名称
     * @return SysDict
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    public SysDict queryDictByName(final String dictName) {
        return mapper.selectOne(Wrappers.<SysDict>lambdaQuery().eq(SysDict::getDictName, dictName));
    }

    /**
     * 查询字典项
     *
     * @param dictCode - 字典编码
     * @return SysDict
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    public SysDict queryDictByCode(final String dictCode) {
        return mapper.selectOne(Wrappers.<SysDict>lambdaQuery().eq(SysDict::getDictCode, dictCode));
    }

    /**
     * 保存字典项
     *
     * @param sysDict - 字典项
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    @HashCacheEvict(hashIdentification = CacheConstant.SYS_DICT_CACHE)
    public Boolean saveDict(final SysDict sysDict) {
        // 影响行数
        int insert = baseMapper.insert(sysDict);
        return insert > 0;
    }

    /**
     * 删除字典项
     *
     * @param dictIdentification - 字典项标识
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    @HashCacheEvict(hashIdentification = CacheConstant.SYS_DICT_CACHE)
    public Boolean deleteDict(final Long dictIdentification) {
        // 影响行数
        int delete = mapper.deleteById(dictIdentification);
        return delete > 0;
    }

    /**
     * 更新字典项
     *
     * @param sysDict - 字典项修改对象
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    @HashCacheEvict(hashIdentification = CacheConstant.SYS_DICT_CACHE, hashKey = "#sysDict.dictCode")
    public Boolean updateByDictIdentification(final SysDict sysDict) {
        // 影响行数
        int update = mapper.updateById(sysDict);
        return update > 0;
    }

    /**
     * 根据字典编码（code）获取下拉
     *
     * @param dictCode - 字典编码（code）
     * @return List<DictVO>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    @HashCache(hashIdentification = CacheConstant.SYS_DICT_CACHE, hashKey = "#dictCode")
    public List<DictVO> queryDictItemsByDictCode(final String dictCode) {
        return mapper.queryDictItemsByDictCode(dictCode);
    }

    /**
     * 验证表、表字段是否存在
     *
     * @param table      - 表名
     * @param fieldArray - 字段数组
     * @return String
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    public Boolean verifyTable(final String table, final String[] fieldArray) {
        List<String> name = mapper.verifyTable(table, fieldArray);
        return name.size() == fieldArray.length;
    }

    /**
     * 通过查询指定表（table）的 字段（text、code）进行条件SQL语句（filterSql）检索查询数据成为字典结果
     *
     * @param sysDictItemsQuery - 指定表、字段的下拉查询对象
     * @return List<DictVO>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    @HashCache(hashIdentification = CacheConstant.SYS_DICT_TABLE_CACHE, hashKey = "#sysDictItemsQuery.table + ':' + #sysDictItemsQuery.textField + ':' + #sysDictItemsQuery.codeField + ':' + #sysDictItemsQuery.filterSql")
    public List<DictVO> queryTableDictItemsByParameter(final DictItemsQueryDTO sysDictItemsQuery) {
        log.debug("无缓存 queryTableDictItemsByParameter 的时候调用这里！");
        return mapper.queryTableDictItemsByParameter(sysDictItemsQuery);
    }

    /**
     * 通过查询指定表（table）的 字段（text、code）进行指定内容（code）的检索查询数据成为字典结果
     *
     * @param sysDictItemsByCodeQuery - 指定表、字段的指定内容下拉查询对象
     * @return List<DictVO>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/12 9:55
     */
    @Override
    public List<DictVO> queryTableDictItemsByCode(final DictItemsByCodeQueryDTO sysDictItemsByCodeQuery) {
        log.debug("无缓存 queryTableDictItemsByCode 的时候调用这里！");
        return mapper.queryTableDictItemsByCode(sysDictItemsByCodeQuery);
    }

    /**
     * 条件查询字典树
     *
     * @param queryDictTree - 字典树查询对象
     * @return List<DropDownBoxTreeVO> - 字典树
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/8/3 16:39
     */
    @Override
    public List<DropDownBoxTreeVO> queryDictTreeListByParameter(final QueryDictTreeDTO queryDictTree) {
        log.debug("无缓存 queryDictTreeListByParameter 的时候调用这里！");
        return mapper.queryDictTreeListByParameter(queryDictTree);
    }

}